home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume7 / xmail / patch1.01 next >
Encoding:
Internet Message Format  |  1990-06-01  |  56.9 KB

  1. Path: uunet!seismo!ukma!rex!uflorida!haven!decuac!decwrl!elroy.jpl.nasa.gov!ames!sun-barr!newstop!sun!news
  2. From: news@sun.Eng.Sun.COM (news)
  3. Newsgroups: comp.sources.x
  4. Subject: v07i081: xmail -- Mail front end for X11, Patch1, Part01/06
  5. Message-ID: <136496@sun.Eng.Sun.COM>
  6. Date: 1 Jun 90 03:39:47 GMT
  7. Organization: Sun Microsystems, Inc. - Mtn View, CA
  8. Lines: 1671
  9. Approved: argv@sun.com
  10.  
  11. Submitted-by: parns.nsc.com!michael (Michael C. Wagnitz)
  12. Posting-number: Volume 7, Issue 81
  13. Archive-name: xmail/patch1.01
  14. Patch-To: xmail: Volume 6, Issue 41-46
  15.  
  16. The following files constitute the first (and only) official patch to the
  17. Mail X11 front-end xmail.  Due to a most fortunate delay in shipment of these
  18. patches, I have been able to re-combine the full set of enhancements originally
  19. announced as two sets of patches into this one complete set.  This should help
  20. to reduce the net bandwidth.
  21.  
  22. After unsharing these files, you will have a MANIFEST of this patch
  23. distribution, a file of CHANGES, and a set of five files named Patch.01[a-e]
  24. that must be concatenated into one patch file (PATCH.01) which is then to be
  25. applied to an original set of xmail sources.
  26.  
  27. My thanks go to the many contributors of patches and suggestions for xmail.
  28.  
  29. #! /bin/sh
  30. # This is a shell archive.  Remove anything before this line, then unpack
  31. # it by saving it into a file and typing "sh file".  To overwrite existing
  32. # files, type "sh file -c".  You can also feed this as standard input via
  33. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  34. # will see the following message at the end:
  35. #        "End of archive 1 (of 5)."
  36. # Contents:  CHANGES MANIFEST Patch.01b
  37. # Wrapped by michael@harley on Tue May 29 10:33:49 1990
  38. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  39. if test -f 'CHANGES' -a "${1}" != "-c" ; then 
  40.   echo shar: Will not clobber existing file \"'CHANGES'\"
  41. else
  42. echo shar: Extracting \"'CHANGES'\" \(6361 characters\)
  43. sed "s/^X//" >'CHANGES' <<'END_OF_FILE'
  44. X
  45. X                                                                   May, 1990
  46. X
  47. X   The following changes have been effected for Patchlevel 1 of xmail.
  48. X
  49. X
  50. XImakefile:    Made improvements in dependencies and SunOS defines.
  51. X        Removed requirement for linkage to system math library.
  52. X
  53. XHelpText.c:    Text revised and reformatted to better fit the help window
  54. X
  55. XMailwatch.c:    Corrected illegal pointer combinations and added resources
  56. X        to allow the user to specify the number of times to ring the
  57. X        bell when new mail has arrived.  Fixed new mail bell to ring
  58. X        only if flag is not already up.
  59. X
  60. XMailwatch.h:    Eliminated warning for duplicate XtNfile definition
  61. X
  62. Xactions.c:    Corrected illegal pointer combinations, added support for
  63. X        improved index handler and Blind carbon copies.  Also added
  64. X        support for .mailrc "printmail" definition, and improved error
  65. X        messages when attempting to select non-existant or undefined
  66. X        mail folders.  Used integer math instead of sqrt() function to
  67. X        calculate box dimensions for aliases list.
  68. X
  69. XcallMail.c:    Corrected attempts to write to read-only strings, and fixed
  70. X        case where fork child dies for improper command arguments or
  71. X        illegal or unfound image execution which tried to write error
  72. X        messages to the xmail pipe instead of the terminal screen.
  73. X        A dying child process now also terminates the xmail process.
  74. X
  75. Xcallbacks.c:    Added support for external sendmail function, improved index
  76. X        handler, and mail variable 'alwaysignore' which is now used
  77. X        to determine header levels for reply, forward, and printed
  78. X        messages.  If recipient selection fails to find a value for
  79. X        the <Return_Path:> to a message, the <From:> designate is now
  80. X        used, to eliminate failures to provide a <To:> addressee.
  81. X        Also fixed bug in replyalls which failed to pick up names from
  82. X        the original To: field when preparing addresses for the reply.
  83. X
  84. Xdefs.h:        Changed TITLE definition to accomodate use of PATCHLEVEL.
  85. X
  86. Xenvirons.c:    Alias support has been extended to include the word 'group'
  87. X        when manually extracting mail aliases from the user's .mailrc
  88. X        file.  Support has also been included for continuation lines.
  89. X        Mechanisms to expand the MAILRC environment variable definition
  90. X        have been eliminated, so that xmail behaves more like mail.
  91. X        Corrected a bug in getMailEnv to return 'True' for variables
  92. X        which have no additional value, such as 'hold' or 'autoprint'.
  93. X        Changed strchr() calls to index().
  94. X
  95. Xhandler.c:    Function icon_handler() has been added to switch xmail to a
  96. X        dummy mail folder whenever the application is iconified, and
  97. X        to switch back to the previous folder on de-iconification.
  98. X        Improved index_handler() to eliminate repaints of the index
  99. X        window for every deletion or undeletion.  Also added code to
  100. X        display as many new message headers as possible, to elminate
  101. X        unnecessary scrolling of the index window.
  102. X
  103. Xmail.c:        Changed the fputs() to a write() to help eliminate i/o hanging,
  104. X        added Blind Carbon Copy support to the sendMail function, and
  105. X        added XMail class resources to the xterm messsage entry window.
  106. X        Changed strrchr() call declarations to rindex().
  107. X
  108. Xparser.c:    Eliminated multiple redraws of the index window during message
  109. X        deletions, and corrected index message markers for 'N'ew,
  110. X        'D'eleted, and undeleted mail messages.  Corrected a bug in the
  111. X        delete processing to not reread entire message and corrected a
  112. X        bug to erase index and text window datas if no current folder.
  113. X
  114. Xutils.c:    Added use of PATCHLEVEL in determining TITLE version revision
  115. X        and changed calls for strchr() to index().
  116. X
  117. Xwindows.c:    Changed name of "hold" button to "preserve", to better match
  118. X        error message text when used incorrectly, eliminated making
  119. X        the preserve button insensitive, to allow use of "set" menu
  120. X        in any folder, added a "set" menu to the "preserve" command
  121. X        button, to toggle mail variables, "alwaysignore", "autoprint",
  122. X        and "hold", and corrected character processing in the file
  123. X        window, to allow deletion and insertion within the line,
  124. X        instead of always at the end.  Added use of PATCHLEVEL in
  125. X        determining TITLE version revision
  126. X
  127. Xxmail.c:    added support for the -iconic command line option, corrected
  128. X        resource handling for iconGeometry, and improved default font
  129. X        handling for minimum dimensions of the xmail application window.
  130. X        Also fixed processing of geometry specifications for the top
  131. X        level window.  Update the 'what' database string to reflect
  132. X        current version.
  133. X
  134. X
  135. X
  136. XI would like to thank the many contributors of suggestions and actual patches.
  137. XI would also like to thank those persons who sent in complaints, as they were
  138. Xoften the predictors of the many other corrections and enhancements to xmail. 
  139. X
  140. X*) Message size tests in parser.c were extended to include support for DEC
  141. X   mail return on size requests, to prevent core dumps under Ultrix UWS 2.2
  142. X   thanks to patches from Dirk Grunwald <grunwald@foobar.Colorado.EDU>
  143. X
  144. X*) Corrections to Imakefile to eliminate the need to set SunOS dependency
  145. X   flags manually were driven by suggestions from Casey Leedom
  146. X   <casey@gauss.llnl.gov> and David Elliott <dce@smsc.sony.com>.
  147. X
  148. X*) The regular expressions definitions in xmailregex.h were corrected as a
  149. X   result of suggestions from Casey Leedom.
  150. X
  151. X*) Suggestions from Casey Leedom, Mark Williams <msw@cpsc.UCalgary.CA>,
  152. X   and Mark Scholl <scholl@inf.ethz.ch> helped identify a problem in the
  153. X   communications links with mail.  writeMail() now uses a write instead
  154. X   of fputs, and the connection parameters are set for APPEND instead of
  155. X   non-blocking i/o, to eliminate run-away cpu cycles.
  156. X
  157. X*) Many, many illegal pointer combination errors were identified and corrected
  158. X   by Christos Zoulas <christos@guillemin.EE.cornell.edu>
  159. X
  160. X*) Thanks go to Robert Viduya <robert@shangri-la.gatech.ude> for suggestions
  161. X   and assistance in adding an icon handler to switch to a dummy mail folder
  162. X   during iconification, to prevent collisions in mail if run from another
  163. X   process while xmail is running.
  164. X
  165. X*) Support for an alternate sendmail function was provided after receiving
  166. X   suggestions from Jim Blythe <jsblythe%uk.co.gec-mrc@nsfnet-relay.ac.uk>
  167. X
  168. X*) Blind carbon copy support and correction of several bugs were suggested
  169. X   by Jeff Dauber <dauber@parns.nsc.com>
  170. X
  171. X*) Support for mail variables autoprint and hold were corrected thanks to
  172. X   requests from Dwayne Lee <dwayne@asic.nsc.com>
  173. END_OF_FILE
  174. if test 6361 -ne `wc -c <'CHANGES'`; then
  175.     echo shar: \"'CHANGES'\" unpacked with wrong size!
  176. fi
  177. # end of 'CHANGES'
  178. fi
  179. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  180.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  181. else
  182. echo shar: Extracting \"'MANIFEST'\" \(460 characters\)
  183. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  184. X   File Name        Archive #    Description
  185. X-----------------------------------------------------------
  186. X CHANGES                    1    List of enhancements to xmail
  187. X MANIFEST                   1    This shipping list
  188. X Patch.01a                  2    Patch file for xmail
  189. X Patch.01b                  1    Patch file for xmail
  190. X Patch.01c                  3    Patch file for xmail
  191. X Patch.01d                  4    Patch file for xmail
  192. X Patch.01e                  5    Patch file for xmail
  193. END_OF_FILE
  194. if test 460 -ne `wc -c <'MANIFEST'`; then
  195.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  196. fi
  197. # end of 'MANIFEST'
  198. fi
  199. if test -f 'Patch.01b' -a "${1}" != "-c" ; then 
  200.   echo shar: Will not clobber existing file \"'Patch.01b'\"
  201. else
  202. echo shar: Extracting \"'Patch.01b'\" \(46474 characters\)
  203. sed "s/^X//" >'Patch.01b' <<'END_OF_FILE'
  204. X!        tmp[x] = '\0';
  205. X!        foldir[foldlen] = '\0';
  206. X!        strcat(foldir, &tmp[1]);
  207. X!        if ((dirp = opendir(foldir)) != NULL) {
  208. X!           tmp[x++] = '/';
  209. X            tmp[x] = '\0';
  210. X!          }
  211. X!        n = 4;
  212. X!        XtSetArg(args[n], XtNlabel, tmp);                n++;
  213. X!        XtSetArg(args[n], XtNfromHoriz, to_left);            n++;
  214. X!        if (! to_left) XtSetArg(args[n], XtNfromVert, above);        n++;
  215. X  
  216. X!        this_one = XtCreateManagedWidget("listbutton", commandWidgetClass,
  217. X                                                  lw, args, n);
  218. X!        if (dirp != NULL) {
  219. X!           closedir(dirp);
  220. X!           sprintf(trans, dir_Trans, &tmp[1], foldir, "0");
  221. X!           XtOverrideTranslations(this_one, XtParseTranslationTable(trans));
  222. X           }
  223. X        }
  224. X-    }
  225. X     }    /* end - if some trans strlen */
  226. X  /*
  227. X  ** If folders menu exists, pop it up, after setting x,y coordinates
  228. X  */
  229. X   if (popup->core.being_destroyed) {
  230. X!     Bell("No mail folders exist\n");
  231. X     } else {
  232. X      if (! XtIsRealized(popup))        /* see if folder list is small */
  233. X         XtRealizeWidget(popup);        /* enough to fit if anchored at */
  234. X--- 791,836 ----
  235. X               } else {
  236. X                 if (x == 0) tmp[x++] = '+';    /* start folder names with a 'plus' */
  237. X                 tmp[x++] = *p;
  238. X+              }
  239. X            }
  240. X  
  241. X!        if (x) {
  242. X            tmp[x] = '\0';
  243. X!           foldir[foldlen] = '\0';
  244. X!           strcat(foldir, &tmp[1]);
  245. X!           if ((dirp = opendir(foldir)) != NULL) {
  246. X!              tmp[x++] = '/';
  247. X!              tmp[x] = '\0';
  248. X!             }
  249. X!           XtSetArg(args[4], XtNlabel, tmp);
  250. X!           XtSetArg(args[5], XtNfromHoriz, to_left);            n = 6;
  251. X!           if (! to_left) XtSetArg(args[n], XtNfromVert, above);        n++;
  252. X  
  253. X!           this_one = XtCreateManagedWidget("listbutton", commandWidgetClass,
  254. X                                                  lw, args, n);
  255. X!           if (dirp != NULL) {
  256. X!              closedir(dirp);
  257. X!              sprintf(trans, dir_Trans, &tmp[1], foldir, "0");
  258. X!              XtOverrideTranslations(this_one, XtParseTranslationTable(trans));
  259. X!             }
  260. X           }
  261. X        }
  262. X     }    /* end - if some trans strlen */
  263. X  /*
  264. X  ** If folders menu exists, pop it up, after setting x,y coordinates
  265. X  */
  266. X   if (popup->core.being_destroyed) {
  267. X!     if (! *foldir)
  268. X!        Bell("No value set for \"folder\"\n");
  269. X!     else {
  270. X!        if (dirp && !mailpid) {
  271. X!           Bell("No mail folders exist\n");
  272. X!          } else {
  273. X!           foldir[foldlen - 1] = '\0';
  274. X!           sprintf(tmp, "%s not found\n", foldir);
  275. X!           Bell(tmp);
  276. X!          }
  277. X!       }
  278. X     } else {
  279. X      if (! XtIsRealized(popup))        /* see if folder list is small */
  280. X         XtRealizeWidget(popup);        /* enough to fit if anchored at */
  281. X***************
  282. X*** 790,810 ****
  283. X         ad = XtDisplay(w);
  284. X         n = XMail.buttonHeight / 2;
  285. X        } else {
  286. X!        aw = XtWindow(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"));
  287. X!        ad = XtDisplay(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"));
  288. X!  n = XMail.commandMinHeight / 2;
  289. X        }
  290. X      root = RootWindow(ad, DefaultScreen(ad));
  291. X  
  292. X!  XTranslateCoordinates(ad, aw, root, XMail.menuX, n, &x, &y, &dumy);
  293. X  
  294. X!  n = 0;
  295. X!  XtSetArg(args[n], XtNx, x);            n++;
  296. X!  XtSetArg(args[n], XtNy, y);            n++;
  297. X!     XtSetValues(popup, (ArgList) args, n);
  298. X     }
  299. X  
  300. X!  XtFree(List);
  301. X  
  302. X  } /* SetFolders */
  303. X  
  304. X--- 841,860 ----
  305. X         ad = XtDisplay(w);
  306. X         n = XMail.buttonHeight / 2;
  307. X        } else {
  308. X!        aw = XtWindow(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"));
  309. X!        ad = XtDisplay(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"));
  310. X!        n = XMail.commandMinHeight / 2;
  311. X        }
  312. X      root = RootWindow(ad, DefaultScreen(ad));
  313. X  
  314. X!     XTranslateCoordinates(ad, aw, root, XMail.menuX, n, &x, &y, &dumy);
  315. X  
  316. X!     XtSetArg(args[0], XtNx, x);
  317. X!     XtSetArg(args[1], XtNy, y);
  318. X!     XtSetValues(popup, (ArgList) args, 2);
  319. X     }
  320. X  
  321. X!  XtFree((char *)List);
  322. X  
  323. X  } /* SetFolders */
  324. X  
  325. X***************
  326. X*** 820,827 ****
  327. X  String *params;
  328. X  Cardinal *num_params;
  329. X  {
  330. X!  Arg        args[3];
  331. X!  Widget        tw;
  332. X   Window        aw, dumy;
  333. X   Display    *ad;
  334. X   int        indx, status, x, y, scn;
  335. X--- 870,877 ----
  336. X  String *params;
  337. X  Cardinal *num_params;
  338. X  {
  339. X!  Arg        args[2];
  340. X!  Widget        tb, tw;
  341. X   Window        aw, dumy;
  342. X   Display    *ad;
  343. X   int        indx, status, x, y, scn;
  344. X***************
  345. X*** 834,844 ****
  346. X       if (strcmp(params[0], HelpNames[indx]) == 0) break;
  347. X  
  348. X   if (HelpNames[indx]) {
  349. X!     XtTextSetSource(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), "helpWindow"), HelpStrings[indx], (XtTextPosition) 0);
  350. X  /*
  351. X  ** Position help relative to textWindow
  352. X  */
  353. X!     tw  = WidgetOf(WidgetOf(toplevel, "vpane"), "textWindow");
  354. X      aw  = XtWindow(tw);
  355. X      ad  = XtDisplay(tw);
  356. X      scn = DefaultScreen(ad);
  357. X--- 884,895 ----
  358. X       if (strcmp(params[0], HelpNames[indx]) == 0) break;
  359. X  
  360. X   if (HelpNames[indx]) {
  361. X!     tb = WidgetOf(toplevel, "topBox");
  362. X!     XtTextSetSource(WidgetOf(WidgetOf(tb, "help"), "helpWindow"), HelpStrings[indx], (XtTextPosition) 0);
  363. X  /*
  364. X  ** Position help relative to textWindow
  365. X  */
  366. X!     tw  = WidgetOf(tb, "textWindow");
  367. X      aw  = XtWindow(tw);
  368. X      ad  = XtDisplay(tw);
  369. X      scn = DefaultScreen(ad);
  370. X***************
  371. X*** 848,861 ****
  372. X  
  373. X      XtSetArg(args[0], XtNx, x);
  374. X      XtSetArg(args[1], XtNy, y);
  375. X!     XtSetValues(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), args, 2);
  376. X  
  377. X!     XtPopup(WidgetOf(WidgetOf(toplevel, "vpane"), "help"), XtGrabNone);
  378. X     }
  379. X  } /* SetHelp */
  380. X  
  381. X  
  382. X  /*
  383. X  ** @(#)SetPopup() - place named popup at menuX, menuY relative to Widget w.
  384. X  */
  385. X  /* ARGSUSED */
  386. X--- 899,988 ----
  387. X  
  388. X      XtSetArg(args[0], XtNx, x);
  389. X      XtSetArg(args[1], XtNy, y);
  390. X!     XtSetValues(WidgetOf(tb, "help"), args, 2);
  391. X  
  392. X!     XtPopup(WidgetOf(tb, "help"), XtGrabNone);
  393. X     }
  394. X  } /* SetHelp */
  395. X  
  396. X  
  397. X+ /* 
  398. X+ ** @(#)SetMenu() - create a menu for toggling selected mail options
  399. X+ */
  400. X+ XtActionProc
  401. X+ SetMenu(parent, event, params, num_params)
  402. X+ Widget        parent;
  403. X+ XEvent        *event; /* unused */
  404. X+ String        *params;
  405. X+ Cardinal    *num_params;
  406. X+ {
  407. X+  Arg         args[6];
  408. X+  Display        *ad;
  409. X+  Widget        menu, layout, previous, next;
  410. X+  Window         aw, dumy, root;
  411. X+  char        *c, label[BUFSIZ], name[BUFSIZ];        
  412. X+  int        indx, x, y;
  413. X+ 
  414. X+  static String b_Trans =
  415. X+     "<EnterWindow>:    set() \n\
  416. X+      <LeaveWindow>: reset() \n\
  417. X+      <Btn3Up>:    SetCursor(True) notify() SetCursor() unset()";
  418. X+ 
  419. X+  static String m_Trans =
  420. X+     "<Btn3Up>:    MenuPopdown(set_menu)";
  421. X+ 
  422. X+  static String list[] = { "alwaysignore", "autoprint", "hold", NULL };
  423. X+ 
  424. X+ 
  425. X+  menu = XtNameToWidget(parent, "set_menu");
  426. X+ 
  427. X+  if (! menu || menu->core.being_destroyed) {
  428. X+     XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(m_Trans));
  429. X+     menu = XtCreatePopupShell("set_menu",overrideShellWidgetClass,parent,args,1);
  430. X+ 
  431. X+     XtSetArg(args[0], XtNdefaultDistance, (XtArgVal) 1);
  432. X+     layout = XtCreateManagedWidget("menu", formWidgetClass, menu, args, ONE);
  433. X  /*
  434. X+ ** create the menu buttons
  435. X+ */
  436. X+     indx = XTextWidth(TextFontStr, " ", 1) * 18 + 12;
  437. X+     previous = NULL;
  438. X+     XtSetArg(args[0], XtNwidth, indx);
  439. X+     XtSetArg(args[1], XtNfont, TextFontStr);
  440. X+     XtSetArg(args[2], XtNjustify, XtJustifyLeft);
  441. X+     XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(b_Trans));
  442. X+     for (indx = 0; list[indx] != NULL; indx++) {
  443. X+         strcpy(label, "set ");
  444. X+         if ((c = GetMailEnv(list[indx])) != NULL) {
  445. X+            strcat(label, "no");
  446. X+            XtFree(c);
  447. X+           }
  448. X+         strcat(label, list[indx]);        /* set window name by label */
  449. X+         strcpy(name, &label[4]);
  450. X+         XtSetArg(args[4], XtNlabel, label);
  451. X+         XtSetArg(args[5], XtNfromVert, previous);
  452. X+         next = XtCreateManagedWidget(name, commandWidgetClass, layout, args, 6);
  453. X+         XtAddCallback(next, XtNcallback, (XtCallbackProc) DoSet, NULL);
  454. X+         previous = next;
  455. X+        }
  456. X+ 
  457. X+     XtRealizeWidget(menu);
  458. X+    }
  459. X+ 
  460. X+  aw = XtWindow(parent);
  461. X+  ad = XtDisplay(parent);
  462. X+  indx = XMail.buttonHeight / 2;
  463. X+  root = RootWindow(ad, DefaultScreen(ad));
  464. X+ 
  465. X+  XTranslateCoordinates(ad, aw, root, XMail.menuX, indx, &x, &y, &dumy);
  466. X+ 
  467. X+  XtSetArg(args[0], XtNx, x);
  468. X+  XtSetArg(args[1], XtNy, y);
  469. X+  XtSetValues(menu, (ArgList) args, 2);
  470. X+ } /* SetMenu */
  471. X+ 
  472. X+ 
  473. X+ /*
  474. X  ** @(#)SetPopup() - place named popup at menuX, menuY relative to Widget w.
  475. X  */
  476. X  /* ARGSUSED */
  477. X***************
  478. X*** 939,945 ****
  479. X   cm.format = 32;
  480. X   cm.data.l[0] = XA_PRIMARY;
  481. X  
  482. X!  XSendEvent(XtDisplay(w), cm.window, TRUE, NoEventMask, &cm);
  483. X  
  484. X   for (; *s && !isdigit(*s); s++);
  485. X   left = s - IndexBuf;
  486. X--- 1066,1072 ----
  487. X   cm.format = 32;
  488. X   cm.data.l[0] = XA_PRIMARY;
  489. X  
  490. X!  XSendEvent(XtDisplay(w), cm.window, TRUE, NoEventMask, (XEvent *) &cm);
  491. X  
  492. X   for (; *s && !isdigit(*s); s++);
  493. X   left = s - IndexBuf;
  494. X***************
  495. X*** 963,971 ****
  496. X  String        *params;
  497. X  Cardinal    *num_params;
  498. X  {
  499. X!  caddr_t    client_data;
  500. X!  caddr_t    call_data;
  501. X! 
  502. X!  client_data = params[0];
  503. X!  DoQuit(w, client_data, call_data);
  504. X  } /* Quit */
  505. X--- 1090,1094 ----
  506. X  String        *params;
  507. X  Cardinal    *num_params;
  508. X  {
  509. X!  DoQuit(w, *params, NULL);
  510. X  } /* Quit */
  511. X*** ../v1.0/callMail.c    Sun May 27 21:05:43 1990
  512. X--- callMail.c    Sun May 27 21:09:56 1990
  513. X***************
  514. X*** 43,56 ****
  515. X  #include    <sgtty.h>
  516. X  #include    "global.h"
  517. X  
  518. X! FILE               *mailfp = NULL;        /* file pointer to mail */
  519. X  int                mail_fd;        /* mail process master tty id */
  520. X  int                mailpid;        /* mail process id */
  521. X  int                mailInputId;        /* mail input id */
  522. X  
  523. X- static char     *pty = "/dev/pty??";    /* master side of pseudo-terminal */
  524. X- static char     *tty = "/dev/tty??";    /* slave side of pseudo-terminal */
  525. X- 
  526. X  /*
  527. X   *  Xmail talks to mail through a pseudo terminal which is a pair of master
  528. X   *  and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
  529. X--- 43,57 ----
  530. X  #include    <sgtty.h>
  531. X  #include    "global.h"
  532. X  
  533. X! #define PTYTEMPL "/dev/pty??"
  534. X! #define TTYTEMPL "/dev/tty??"
  535. X! 
  536. X  int                mail_fd;        /* mail process master tty id */
  537. X  int                mailpid;        /* mail process id */
  538. X  int                mailInputId;        /* mail input id */
  539. X+ char        pty[10];        /* master side of pseudo-terminal */
  540. X+ char        tty[10];        /* slave side of pseudo-terminal */
  541. X  
  542. X  /*
  543. X   *  Xmail talks to mail through a pseudo terminal which is a pair of master
  544. X   *  and slave devices: /dev/pty?? and /dev/tty??, where ?? goes from p0 to
  545. X***************
  546. X*** 65,70 ****
  547. X--- 66,72 ----
  548. X   int  i, master; 
  549. X   char c;
  550. X  
  551. X+  (void) strcpy(pty, PTYTEMPL);
  552. X   for (c='p'; c<='s'; c++) {
  553. X       pty[8] = c;
  554. X       for (i=0; i<16; i++) {
  555. X***************
  556. X*** 86,91 ****
  557. X--- 88,94 ----
  558. X  {
  559. X   int slave;
  560. X  
  561. X+  (void) strcpy(tty, TTYTEMPL);
  562. X   tty[8] = pty[8];
  563. X   tty[9] = pty[9];
  564. X   if ((slave = open(tty, O_RDWR)) != -1) {
  565. X***************
  566. X*** 106,122 ****
  567. X  int argc;
  568. X  char *argv[];
  569. X  {
  570. X!  struct sgttyb Sgtty;
  571. X!  int           master;            /* file descriptor of master pty */
  572. X!  int           slave;            /* file descriptor to slave pty */
  573. X!  char          *Mailpgm,        /* name of executable Mailpgm */
  574. X!                errmsg[BUFSIZ];
  575. X  
  576. X!  Mailpgm = (char *) getenv("XMAILER");    /* first looks up env var */
  577. X!  if (Mailpgm == NULL)
  578. X!     Mailpgm = XtNewString(XMAILER);
  579. X    
  580. X!  master = openMaster();
  581. X   slave = openSlave();
  582. X  
  583. X   ioctl(slave, TIOCGETP, &Sgtty);
  584. X--- 109,124 ----
  585. X  int argc;
  586. X  char *argv[];
  587. X  {
  588. X!  struct sgttyb    Sgtty;
  589. X!  int        slave;            /* file descriptor to slave pty */
  590. X!  char        *Mailpgm;        /* name of executable Mailpgm */
  591. X!  char        buf[BUFSIZ];
  592. X  
  593. X! 
  594. X!  if (! (Mailpgm = (char *)getenv("XMAILER")))    /* first looks up env var */
  595. X!     Mailpgm = "Mail";
  596. X    
  597. X!  mail_fd = openMaster();
  598. X   slave = openSlave();
  599. X  
  600. X   ioctl(slave, TIOCGETP, &Sgtty);
  601. X***************
  602. X*** 125,158 ****
  603. X  
  604. X   mailpid = fork();
  605. X   if (mailpid == -1) {
  606. X!     perror("Cannot fork mail process");
  607. X      exit(1);
  608. X     } else if (mailpid) { 
  609. X               /* 
  610. X                * Parent : close the slave side of pty
  611. X                *          close stdin and stdout
  612. X!               *          set the mail file descriptor to nonblocking mode
  613. X!               *          open file pointer with read/write access to mail
  614. X!               *          set unbuffered mode
  615. X                *          register mail input with X
  616. X                */
  617. X               close(slave);
  618. X!              if (master != 0)        /* if we're restarting, master IS 0 */
  619. X                  close(0);
  620. X               close(1);
  621. X!              fcntl(master, F_SETFL, FNDELAY);
  622. X!              mail_fd = master;            /* use descriptor for reads */
  623. X!              mailfp = fdopen(master, "r+");    /* need mailfp for fputs */
  624. X!              setbuf(mailfp, NULL);
  625. X!              mailInputId = XtAddInput(master, XtInputReadMask, readMail, NULL);
  626. X              } else { 
  627. X               /* 
  628. X!               * Child : close master side of pty
  629. X                *         redirect stdin, stdout, stderr of mail to pty
  630. X                *         unbuffer output data from mail
  631. X                *         exec mail with arguments
  632. X                */
  633. X!              close(master);
  634. X               dup2(slave, 0);
  635. X               dup2(slave, 1);
  636. X               dup2(slave, 2);
  637. X--- 127,155 ----
  638. X  
  639. X   mailpid = fork();
  640. X   if (mailpid == -1) {
  641. X!     perror("callMail: Cannot fork Mail process");
  642. X      exit(1);
  643. X     } else if (mailpid) { 
  644. X               /* 
  645. X                * Parent : close the slave side of pty
  646. X                *          close stdin and stdout
  647. X!               *          set the mail file descriptor to append mode
  648. X                *          register mail input with X
  649. X                */
  650. X               close(slave);
  651. X!              if (mail_fd != 0)        /* if we're restarting, mail_fd IS 0 */
  652. X                  close(0);
  653. X               close(1);
  654. X!              fcntl(mail_fd, F_SETFL, FAPPEND);
  655. X!              mailInputId = XtAddInput(mail_fd, XtInputReadMask, readMail, NULL);
  656. X              } else { 
  657. X               /* 
  658. X!               * Child : close mail_fd side of pty
  659. X                *         redirect stdin, stdout, stderr of mail to pty
  660. X                *         unbuffer output data from mail
  661. X                *         exec mail with arguments
  662. X                */
  663. X!              close(mail_fd);
  664. X               dup2(slave, 0);
  665. X               dup2(slave, 1);
  666. X               dup2(slave, 2);
  667. X***************
  668. X*** 162,169 ****
  669. X               setbuf(stdout, NULL);
  670. X               argv[0] = Mailpgm;
  671. X               execvp(Mailpgm, argv);
  672. X!              sprintf(errmsg, "callMail: Cannot call %s", Mailpgm);
  673. X!              perror(errmsg);
  674. X               exit(1);
  675. X              }
  676. X  } /* callMail */
  677. X--- 159,177 ----
  678. X               setbuf(stdout, NULL);
  679. X               argv[0] = Mailpgm;
  680. X               execvp(Mailpgm, argv);
  681. X!              /*
  682. X!               * If we fail to make contact, we must re-establish
  683. X!               * access to the terminal screen that started us for
  684. X!               * our error message, because we don't want to send
  685. X!               * it up the xmail pipe.  Also, terminate our parent.
  686. X!               */
  687. X!              if ((slave = open("/dev/tty", O_RDWR)) != -1) {
  688. X!                 dup2(slave, 1);
  689. X!                 dup2(slave, 2);
  690. X!                 perror(Mailpgm);
  691. X!                }
  692. X!              sprintf(buf, "kill -INT %s\n", &tmpName[10]);
  693. X!              system(buf);
  694. X               exit(1);
  695. X              }
  696. X  } /* callMail */
  697. X*** ../v1.0/callbacks.c    Sun May 27 21:05:44 1990
  698. X--- callbacks.c    Sun May 27 21:09:57 1990
  699. X***************
  700. X*** 30,35 ****
  701. X--- 30,36 ----
  702. X  #include "global.h"
  703. X  #include <sys/wait.h>
  704. X  #include <sys/stat.h>
  705. X+ #include <pwd.h>
  706. X  
  707. X  
  708. X  /*
  709. X***************
  710. X*** 91,96 ****
  711. X--- 92,98 ----
  712. X   FILE        *fp;
  713. X   char        *p, *record, *folder, *getenv();
  714. X   char        From[BUFSIZ], Copy[BUFSIZ], s[BUFSIZ];
  715. X+  int        n;
  716. X   struct stat    st_buf;
  717. X  
  718. X  
  719. X***************
  720. X*** 115,120 ****
  721. X--- 117,125 ----
  722. X      if (*CcBuf)
  723. X         fprintf(fp, "Cc: %s\n", alias(CcBuf));
  724. X  
  725. X+     if (*BccBuf)
  726. X+        fprintf(fp, "Bcc: %s\n", alias(BccBuf));
  727. X+ 
  728. X      fprintf(fp, "\n");            /* separate header from text */
  729. X      fclose(fp);
  730. X     }
  731. X***************
  732. X*** 126,133 ****
  733. X      */
  734. X      if (*Recipient && (*SubjBuf ||
  735. X         (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
  736. X!        sprintf(s, "cat %s_ %s | /usr/lib/sendmail -toi -om 2> /dev/null", tmpName, tmpName);
  737. X         system(s);
  738. X  /*
  739. X  ** If user has set 'record' in their .mailrc, add a message copy to that file
  740. X  */
  741. X--- 131,141 ----
  742. X      */
  743. X      if (*Recipient && (*SubjBuf ||
  744. X         (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
  745. X!        if ((p = GetMailEnv("sendmail")) == NULL)
  746. X!             p = XtNewString("/usr/lib/sendmail");
  747. X!        sprintf(s, "cat %s_ %s | %s -toi -om 2> /dev/null", tmpName, tmpName, p);
  748. X         system(s);
  749. X+        XtFree(p);
  750. X  /*
  751. X  ** If user has set 'record' in their .mailrc, add a message copy to that file
  752. X  */
  753. X***************
  754. X*** 177,187 ****
  755. X                    sprintf(Copy, "%s/%s", getenv("HOME"), &record[1]);
  756. X            XtFree(record);
  757. X           }
  758. X!        if (*Recipient && (*SubjBuf ||
  759. X!           (stat(tmpName, &st_buf) == 0 && st_buf.st_size))) {
  760. X            sprintf(s, "cat %s_ %s >> %s 2> /dev/null", tmpName, tmpName, Copy);
  761. X            system(s);
  762. X!           sprintf(s, "Canceled letter appended to %s\n", Copy);
  763. X            Bell(s);
  764. X           } else Bell("Nothing to save in your dead letter box\n");
  765. X        }
  766. X--- 185,202 ----
  767. X                    sprintf(Copy, "%s/%s", getenv("HOME"), &record[1]);
  768. X            XtFree(record);
  769. X           }
  770. X!        st_buf.st_size = 0;        /* (in case msg file does not exist) */
  771. X!        if (*Recipient || *SubjBuf ||
  772. X!           (stat(tmpName, &st_buf) == 0 && st_buf.st_size)) {
  773. X!           n = st_buf.st_size;            /* remember num bytes in msg */
  774. X!           if (stat((char *)sprintf(s, "%s_", tmpName), &st_buf) == 0)
  775. X!              n += st_buf.st_size;        /* include bytes in header */
  776. X!           st_buf.st_size = -1;            /* see if our target exists */
  777. X!           stat(Copy, &st_buf);
  778. X            sprintf(s, "cat %s_ %s >> %s 2> /dev/null", tmpName, tmpName, Copy);
  779. X            system(s);
  780. X!           sprintf(s, "\"%s\" [%s] (%d bytes)\n", Copy,
  781. X!                  (st_buf.st_size >= 0) ? "Appended" : "New file", n);
  782. X            Bell(s);
  783. X           } else Bell("Nothing to save in your dead letter box\n");
  784. X        }
  785. X***************
  786. X*** 213,228 ****
  787. X   else if (strcmp(Command, "file %\n") != 0 && strcmp(Command, "inc\n") != 0)
  788. X           Bell("No mail\n");        /* But if no new mail, complain */
  789. X        else {
  790. X!          for (n = 0; n < mailargc; n++) {
  791. X!              if (strcmp(mailargv[n], "-f") == 0) {
  792. X!                 for (i = n + 2; i <= mailargc;) mailargv[n++] = mailargv[i++];
  793. X!                 mailargc -= 2;        /* throw away any folder argument */
  794. X!                 n -= 2;            /* re-examine new mailargv value */
  795. X!                }
  796. X!             }
  797. X           callMail(mailargc, mailargv);    /* restart the mail connections */
  798. X           strcpy(Command, "Start");    /* Let em know we've re-started */
  799. X!          UnsetNewmail(w, closure, call_data);
  800. X     }
  801. X  } /* DoIt */
  802. X  
  803. X--- 228,240 ----
  804. X   else if (strcmp(Command, "file %\n") != 0 && strcmp(Command, "inc\n") != 0)
  805. X           Bell("No mail\n");        /* But if no new mail, complain */
  806. X        else {
  807. X!          if (strcmp(mailargv[mailargc - 2], "-f") == 0) {
  808. X!             mailargc -= 2;        /* throw away any folder argument */
  809. X!             mailargv[mailargc] = NULL;    /* and NULL end of argument list */
  810. X!            }
  811. X           callMail(mailargc, mailargv);    /* restart the mail connections */
  812. X           strcpy(Command, "Start");    /* Let em know we've re-started */
  813. X!          UnsetNewmail(w, NULL, NULL);
  814. X     }
  815. X  } /* DoIt */
  816. X  
  817. X***************
  818. X*** 265,271 ****
  819. X--- 277,308 ----
  820. X  } /* DoQuit */
  821. X  
  822. X  
  823. X+ /*
  824. X+ ** @(#)DoSet() - send specified set request to mail and destroy current menu.
  825. X+ */
  826. X  /* ARGSUSED */
  827. X+ XtCallbackProc
  828. X+ DoSet(w, closure, call_data)
  829. X+ Widget    w;
  830. X+ caddr_t    closure;
  831. X+ caddr_t    call_data;
  832. X+ {
  833. X+  char    *c, buf[32];
  834. X+ 
  835. X+ 
  836. X+  if (! mailpid)                /* If connections are okay,... */
  837. X+     Bell("No mail\n");            /* if no new mail, complain */
  838. X+  else {
  839. X+     sprintf(buf, "set %s", w->core.name);
  840. X+     c = QueryMail(buf);
  841. X+     XtFree(c);
  842. X+ 
  843. X+     XtDestroyWidget(XtParent(XtParent(w)));
  844. X+    }
  845. X+ } /* DoSet */
  846. X+ 
  847. X+ 
  848. X+ /* ARGSUSED */
  849. X  /*
  850. X  ** @(#)DoWith() - send client_data command to mail with selected msg number
  851. X  */
  852. X***************
  853. X*** 281,288 ****
  854. X   if (! mailpid)
  855. X      Bell("No mail\n");
  856. X   else {
  857. X!     pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
  858. X      num = PositionToMsgNumber(pos);    /* no current message returns zero */
  859. X      if (num) sprintf(Command, "%s %d\n", client_data, num);
  860. X      else sprintf(Command, "%s \n", client_data);
  861. X      writeMail(Command);
  862. X--- 318,326 ----
  863. X   if (! mailpid)
  864. X      Bell("No mail\n");
  865. X   else {
  866. X!     pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
  867. X      num = PositionToMsgNumber(pos);    /* no current message returns zero */
  868. X+     if (*client_data == 'u' && IndexBuf[pos + 1] != 'D') num = 0;
  869. X      if (num) sprintf(Command, "%s %d\n", client_data, num);
  870. X      else sprintf(Command, "%s \n", client_data);
  871. X      writeMail(Command);
  872. X***************
  873. X*** 353,359 ****
  874. X         }
  875. X      sprintf(buf, "File: +%s%s", tmp, folder_name);
  876. X     }
  877. X!  writeText(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "fileWindow"), buf, 0);
  878. X  } /* GetFolderName */
  879. X  
  880. X  
  881. X--- 391,397 ----
  882. X         }
  883. X      sprintf(buf, "File: +%s%s", tmp, folder_name);
  884. X     }
  885. X!  writeText(WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "fileWindow"), buf, 0);
  886. X  } /* GetFolderName */
  887. X  
  888. X  
  889. X***************
  890. X*** 371,388 ****
  891. X   Cardinal    *num_params;
  892. X   FILE        *fp;
  893. X   Position    pos;
  894. X!  String        *params, p, q, r, txt, author, subject, others, date, reference;
  895. X!  XEvent        *event;
  896. X   int        erasable = 0;
  897. X   
  898. X  
  899. X!  txt = author = subject = others = date = reference = "";
  900. X   if (*client_data != 's') {
  901. X      if ((fp = fopen(tmpName, "w")) == NULL)
  902. X         Bell("xmail: Cannot open temp file for writing\n");
  903. X  
  904. X!     pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
  905. X!     sprintf(Command, "P %d", PositionToMsgNumber(pos));
  906. X      txt = QueryMail(Command);
  907. X      if (fp) {
  908. X         switch (*client_data) {
  909. X--- 409,438 ----
  910. X   Cardinal    *num_params;
  911. X   FILE        *fp;
  912. X   Position    pos;
  913. X!  String        *params, p, q, r;
  914. X!  String        txt, ccList, author, subject, others, date, reference, empty;
  915. X!  char        *us, *getlogin();
  916. X   int        erasable = 0;
  917. X+  int        alwaysIgnore;
  918. X   
  919. X  
  920. X!  txt = ccList = author = subject = others = date = reference = empty = "";
  921. X   if (*client_data != 's') {
  922. X      if ((fp = fopen(tmpName, "w")) == NULL)
  923. X         Bell("xmail: Cannot open temp file for writing\n");
  924. X  
  925. X!     pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
  926. X! 
  927. X!     if (p = GetMailEnv("alwaysignore")) {
  928. X!        XtFree(p);
  929. X!        alwaysIgnore = 1;
  930. X!       } else alwaysIgnore = 0;
  931. X! 
  932. X!     if (alwaysIgnore)        /* use 'alwaysignore' to decide how we print */
  933. X!        sprintf(Command, "p %d", PositionToMsgNumber(pos));
  934. X!     else
  935. X!        sprintf(Command, "P %d", PositionToMsgNumber(pos));
  936. X! 
  937. X      txt = QueryMail(Command);
  938. X      if (fp) {
  939. X         switch (*client_data) {
  940. X***************
  941. X*** 419,429 ****
  942. X  /*
  943. X  ** strip author, subject, and Carbon copy information from the selected message
  944. X  */
  945. X      for (p = txt; *p; p++) {
  946. X!         if (strcmp(p, "") == 0 || strncmp(p, "Status:", 7) == 0) break;
  947. X  
  948. X          if (strncmp(p, "Return-Path:", 12) == 0) {
  949. X!            author = p + 14;
  950. X             for (p = author; *p && *p != '>'; p++);
  951. X             if (*p) *p++ = '\0';
  952. X             for (; *p && *p != '\n'; p++);
  953. X--- 469,484 ----
  954. X  /*
  955. X  ** strip author, subject, and Carbon copy information from the selected message
  956. X  */
  957. X+     if (alwaysIgnore) {        /* we must now get full headers, for data */
  958. X+        XtFree(txt);
  959. X+        sprintf(Command, "P %d", PositionToMsgNumber(pos));
  960. X+        txt = QueryMail(Command);
  961. X+       }
  962. X      for (p = txt; *p; p++) {
  963. X!         if (strcmp(p, empty) == 0 || strncmp(p, "Status:", 7) == 0) break;
  964. X  
  965. X          if (strncmp(p, "Return-Path:", 12) == 0) {
  966. X!            author = p + 14;        /* step over the opening '<' chevron */
  967. X             for (p = author; *p && *p != '>'; p++);
  968. X             if (*p) *p++ = '\0';
  969. X             for (; *p && *p != '\n'; p++);
  970. X***************
  971. X*** 441,446 ****
  972. X--- 496,507 ----
  973. X             if (*p) *p = '\0';
  974. X            }
  975. X  
  976. X+         else if (strncmp(p, "To:", 3) == 0) {
  977. X+            others = p + 4;
  978. X+            for (p = others; *p && *p != '\n'; p++);
  979. X+            if (*p) *p = '\0';
  980. X+           }
  981. X+ 
  982. X          else if (strncmp(p, "Subject:", 8) == 0) {
  983. X             subject = p + 9;
  984. X             for (p = subject; *p && *p != '\n'; p++);
  985. X***************
  986. X*** 448,485 ****
  987. X            }
  988. X  
  989. X          else if (strncmp(p, "Cc:", 3) == 0) {
  990. X!            others = p + 4;
  991. X!            for (p = others; *p && *p != '\n'; p++);
  992. X             if (*p) *p = '\0';
  993. X            }
  994. X          else for (; *p && *p != '\n'; p++);
  995. X         } /* end - for all of message body */
  996. X  
  997. X!     if (*client_data != 'a' && *client_data != 'A')
  998. X!        others = "";    /* If not [rR]eplyall, make sender enter any Cc: */
  999. X  
  1000. X      if (fp) fclose(fp);
  1001. X  
  1002. X      XtFree(txt);
  1003. X     } /* end - if client_data does not equal 's' */
  1004. X  
  1005. X!  if (*client_data != 'S' && *client_data != 's')
  1006. X      strcpy(Recipient, author);
  1007. X  
  1008. X!  strcpy(InReply, "");
  1009. X   if (*client_data != 's' && *reference && *date) {
  1010. X      r = (*client_data == 'S') ? "Forwarding" : "In-Reply-To";
  1011. X      sprintf(InReply, "%s: Mail from '%s' dated %s", r, reference, date);
  1012. X     }
  1013. X  
  1014. X   if (*subject) {
  1015. X!     strcpy(SubjBuf, "");
  1016. X!     if (strncmp(subject, "Re: ", 4) != 0)
  1017. X         strcat(SubjBuf, "Re: ");
  1018. X      strcat(SubjBuf, subject);
  1019. X     }
  1020. X  
  1021. X!  strcpy(CcBuf, others);
  1022. X  
  1023. X   sendMail(w);
  1024. X  } /* Reply */
  1025. X--- 509,592 ----
  1026. X            }
  1027. X  
  1028. X          else if (strncmp(p, "Cc:", 3) == 0) {
  1029. X!            ccList = p + 4;
  1030. X!            for (p = ccList; *p && *p != '\n'; p++);
  1031. X             if (*p) *p = '\0';
  1032. X            }
  1033. X          else for (; *p && *p != '\n'; p++);
  1034. X         } /* end - for all of message body */
  1035. X  
  1036. X!     if (*client_data != 'a' && *client_data != 'A') {
  1037. X!        ccList = empty;    /* If not [rR]eplyall, make sender enter any Cc: */
  1038. X!        others = empty;
  1039. X!       } else {        /* otherwise, remove ourself from the others list */
  1040. X!        us = getlogin();
  1041. X!        if (! us) {
  1042. X!           struct passwd *pw = getpwuid(getuid());
  1043. X  
  1044. X+           if (pw)
  1045. X+              us = pw->pw_name;
  1046. X+          }
  1047. X+        for (p = others; *us && *p; p++) {
  1048. X+            if (strncmp(p, us, strlen(us)) == 0) {
  1049. X+               for (us = p + strlen(us); *us && *us != ',' && *us != ' ';) us++;
  1050. X+               for (; *us && (*us == ',' || *us == ' ');) us++;
  1051. X+               for (; *us;) *p++ = *us++;
  1052. X+               *p = '\0';
  1053. X+               break;
  1054. X+              }
  1055. X+            while (*p && *p != ',' && *p != ' ') p++;
  1056. X+            while (*p && (*p == ',' || *p == ' ')) p++;
  1057. X+            p--;
  1058. X+           }
  1059. X+       }
  1060. X+ 
  1061. X      if (fp) fclose(fp);
  1062. X  
  1063. X      XtFree(txt);
  1064. X     } /* end - if client_data does not equal 's' */
  1065. X  
  1066. X!  strcpy(Recipient, empty);
  1067. X! /*
  1068. X! ** If message did not have a 'Return-Path', use 'From' for reply recipient
  1069. X! */
  1070. X!  if (*client_data != 'S' && *client_data != 's') {
  1071. X      strcpy(Recipient, author);
  1072. X+     if (! *Recipient && *reference) {
  1073. X+        erasable = 0;
  1074. X+        author = reference;
  1075. X+        for (p = author; *p && *p != ' '; p++);
  1076. X+        if (*p) {
  1077. X+           erasable = 1;
  1078. X+           *p = '\0';
  1079. X+          }
  1080. X+        strcpy(Recipient, author);
  1081. X+        if (erasable) *p = ' ';
  1082. X+       }
  1083. X+     if (*others && (*client_data == 'a' || *client_data == 'A')) {
  1084. X+        if (LASTCH(Recipient) != ',')
  1085. X+           strcat(Recipient, ", ");
  1086. X+        strcat(Recipient, others);
  1087. X+        for (p = Recipient + strlen(Recipient) - 1; *p == ' ' || *p == ','; p--);
  1088. X+        *++p = '\0';            /* drop any trailing ", " garbage */
  1089. X+       }
  1090. X+    }
  1091. X  
  1092. X!  strcpy(InReply, empty);
  1093. X   if (*client_data != 's' && *reference && *date) {
  1094. X      r = (*client_data == 'S') ? "Forwarding" : "In-Reply-To";
  1095. X      sprintf(InReply, "%s: Mail from '%s' dated %s", r, reference, date);
  1096. X     }
  1097. X  
  1098. X+  strcpy(SubjBuf, empty);
  1099. X   if (*subject) {
  1100. X!     if ((strncmp(subject, "Re:", 3) != 0 && strncmp(subject, "Re;", 3) != 0))
  1101. X         strcat(SubjBuf, "Re: ");
  1102. X      strcat(SubjBuf, subject);
  1103. X     }
  1104. X  
  1105. X!  strcpy(CcBuf, ccList);
  1106. X!  strcpy(BccBuf, empty);
  1107. X  
  1108. X   sendMail(w);
  1109. X  } /* Reply */
  1110. X***************
  1111. X*** 503,509 ****
  1112. X   if (! mailpid)
  1113. X      Bell("No mail\n");
  1114. X   else {
  1115. X!  pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "vpane"), "indexWindow"));
  1116. X   num = PositionToMsgNumber(pos);    /* no current message returns zero */
  1117. X  
  1118. X   if (*cmd == 'C' || *cmd == 'S' || *cmd == 'W' || num == 0) {
  1119. X--- 610,616 ----
  1120. X   if (! mailpid)
  1121. X      Bell("No mail\n");
  1122. X   else {
  1123. X!  pos = XtTextGetInsertionPoint(WidgetOf(WidgetOf(toplevel, "topBox"), "indexWindow"));
  1124. X   num = PositionToMsgNumber(pos);    /* no current message returns zero */
  1125. X  
  1126. X   if (*cmd == 'C' || *cmd == 'S' || *cmd == 'W' || num == 0) {
  1127. X***************
  1128. X*** 513,519 ****
  1129. X         sprintf(Command, "%s \n", cmd);
  1130. X        }
  1131. X     } else {
  1132. X!     if ((n = TextGetLastPos(WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "fileWindow")) - StartPos) > 0) {
  1133. X         FileBuf[StartPos + n] = '\0';
  1134. X         p = FileBuf + StartPos;
  1135. X         sprintf(Command, "%s %d %s\n", cmd, num, p);
  1136. X--- 620,626 ----
  1137. X         sprintf(Command, "%s \n", cmd);
  1138. X        }
  1139. X     } else {
  1140. X!     if ((n = TextGetLastPos(WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "fileWindow")) - StartPos) > 0) {
  1141. X         FileBuf[StartPos + n] = '\0';
  1142. X         p = FileBuf + StartPos;
  1143. X         sprintf(Command, "%s %d %s\n", cmd, num, p);
  1144. X***************
  1145. X*** 554,560 ****
  1146. X   Widget    cw;
  1147. X  
  1148. X   if (! Highlighted) {
  1149. X!     cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "Newmail");
  1150. X      XSetWindowBackgroundPixmap(XtDisplay(toplevel), XtWindow(cw), hatch);
  1151. X      XtUnmapWidget(cw);
  1152. X      XtMapWidget(cw);
  1153. X--- 661,667 ----
  1154. X   Widget    cw;
  1155. X  
  1156. X   if (! Highlighted) {
  1157. X!     cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "Newmail");
  1158. X      XSetWindowBackgroundPixmap(XtDisplay(toplevel), XtWindow(cw), hatch);
  1159. X      XtUnmapWidget(cw);
  1160. X      XtMapWidget(cw);
  1161. X***************
  1162. X*** 573,585 ****
  1163. X  caddr_t    client_data;        /* unused */
  1164. X  caddr_t    call_data;        /* unused */
  1165. X  {
  1166. X!  Widget    cw;
  1167. X  
  1168. X   if (Highlighted) {
  1169. X-     cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "vpane"), "commandPanel"), "Newmail");
  1170. X      XSetWindowBackground(XtDisplay(toplevel), XtWindow(cw), cw->core.background_pixel);
  1171. X      XtUnmapWidget(cw);
  1172. X      XtMapWidget(cw);
  1173. X      Highlighted = 0;
  1174. X     }
  1175. X  } /* UnsetNewmail */
  1176. X--- 680,692 ----
  1177. X  caddr_t    client_data;        /* unused */
  1178. X  caddr_t    call_data;        /* unused */
  1179. X  {
  1180. X!  Widget    cw = WidgetOf(WidgetOf(WidgetOf(toplevel, "topBox"), "commandPanel"), "Newmail");
  1181. X  
  1182. X   if (Highlighted) {
  1183. X      XSetWindowBackground(XtDisplay(toplevel), XtWindow(cw), cw->core.background_pixel);
  1184. X      XtUnmapWidget(cw);
  1185. X      XtMapWidget(cw);
  1186. X      Highlighted = 0;
  1187. X+     reset_mailbox(WidgetOf(WidgetOf(toplevel, "icon"), "mailbox"));
  1188. X     }
  1189. X  } /* UnsetNewmail */
  1190. X*** ../v1.0/defs.h    Sun May 27 21:05:48 1990
  1191. X--- defs.h    Sun May 27 21:11:35 1990
  1192. X***************
  1193. X*** 48,65 ****
  1194. X  #include <X11/StringDefs.h>
  1195. X  #include <X11/Shell.h>
  1196. X  #include <X11/Xatom.h>
  1197. X! #ifdef X11R3
  1198. X! #include <X11/Cardinals.h>
  1199. X! #include <X11/VPaned.h>
  1200. X! #include <X11/Form.h>
  1201. X! #include <X11/AsciiText.h>
  1202. X! #include <X11/TextP.h>
  1203. X! #include <X11/Box.h>
  1204. X! #include <X11/List.h>
  1205. X! #include <X11/Command.h>
  1206. X! #include <X11/Dialog.h>
  1207. X! #include <X11/Label.h>
  1208. X! #else
  1209. X  #include <X11/Xaw/Cardinals.h>
  1210. X  #include <X11/Xaw/VPaned.h>
  1211. X  #include <X11/Xaw/Form.h>
  1212. X--- 48,56 ----
  1213. X  #include <X11/StringDefs.h>
  1214. X  #include <X11/Shell.h>
  1215. X  #include <X11/Xatom.h>
  1216. X! 
  1217. X! #if XtSpecificationRelease >= 4
  1218. X! /* R4 */
  1219. X  #include <X11/Xaw/Cardinals.h>
  1220. X  #include <X11/Xaw/VPaned.h>
  1221. X  #include <X11/Xaw/Form.h>
  1222. X***************
  1223. X*** 70,81 ****
  1224. X  #include <X11/Xaw/Command.h>
  1225. X  #include <X11/Xaw/Dialog.h>
  1226. X  #include <X11/Xaw/Label.h>
  1227. X  #endif
  1228. X  
  1229. X! #define    TITLE        "xmail 1.0"    /* program title and version string */
  1230. X! #define    MAXARGS        20        /* max number of args */
  1231. X  #define    StartPos     6        /* size of 'File: ' (del stop point) */
  1232. X- #define    XMAILER        "Mail"        /* name of mail program executable */
  1233. X  #define    LASTCH(s)    (s[strlen(s)-1])
  1234. X  #define    TEXTWIDTH    (TextFontStr->max_bounds.width)
  1235. X  #define    TEXTHEIGHT    (TextFontStr->max_bounds.descent + TextFontStr->max_bounds.ascent)
  1236. X--- 61,82 ----
  1237. X  #include <X11/Xaw/Command.h>
  1238. X  #include <X11/Xaw/Dialog.h>
  1239. X  #include <X11/Xaw/Label.h>
  1240. X+ #else
  1241. X+ /* R3 */
  1242. X+ #include <X11/Cardinals.h>
  1243. X+ #include <X11/VPaned.h>
  1244. X+ #include <X11/Form.h>
  1245. X+ #include <X11/AsciiText.h>
  1246. X+ #include <X11/TextP.h>
  1247. X+ #include <X11/Box.h>
  1248. X+ #include <X11/List.h>
  1249. X+ #include <X11/Command.h>
  1250. X+ #include <X11/Dialog.h>
  1251. X+ #include <X11/Label.h>
  1252. X  #endif
  1253. X  
  1254. X! #define    TITLE        "xmail 1."    /* program title and version string */
  1255. X  #define    StartPos     6        /* size of 'File: ' (del stop point) */
  1256. X  #define    LASTCH(s)    (s[strlen(s)-1])
  1257. X  #define    TEXTWIDTH    (TextFontStr->max_bounds.width)
  1258. X  #define    TEXTHEIGHT    (TextFontStr->max_bounds.descent + TextFontStr->max_bounds.ascent)
  1259. X***************
  1260. X*** 89,94 ****
  1261. X--- 90,97 ----
  1262. X  typedef struct {
  1263. X      String    textFont;        /* xmail text font */
  1264. X      String    helpFont;        /* xmail help font */
  1265. X+     String    iconGeometry;        /* xmail icon geometry */
  1266. X+     String    MFileName;        /* mail option -f filename */
  1267. X      Dimension    shellWidth;        /* xmail window width */
  1268. X      Dimension    fileBoxWidth;        /* file window box width */
  1269. X      Dimension    indexHeight;        /* index window height */
  1270. X***************
  1271. X*** 105,117 ****
  1272. X      Dimension    helpY;            /* help y offset from textWindow */
  1273. X      Dimension    menuX;            /* menu x offset from parent */
  1274. X      Dimension    menuY;            /* menu y offset from parent */
  1275. X! 
  1276. X      Boolean    bellRing;        /* xmail audible bell option */
  1277. X-     Boolean    mailopt_i;        /* mail option -i */
  1278. X      Boolean    mailopt_n;        /* mail option -n */
  1279. X      Boolean    mailopt_U;        /* mail option -U */
  1280. X-     String    MFileName;        /* mail option -f filename */
  1281. X-     String    SubjectStr;        /* mail option -s subject */
  1282. X      Boolean    Show_Last;        /* xmail show latest option -ls */
  1283. X  } XmailResources;
  1284. X  
  1285. X--- 108,117 ----
  1286. X      Dimension    helpY;            /* help y offset from textWindow */
  1287. X      Dimension    menuX;            /* menu x offset from parent */
  1288. X      Dimension    menuY;            /* menu y offset from parent */
  1289. X!     Boolean    iconic;            /* xmail starts in withdrawn state */
  1290. X      Boolean    bellRing;        /* xmail audible bell option */
  1291. X      Boolean    mailopt_n;        /* mail option -n */
  1292. X      Boolean    mailopt_U;        /* mail option -U */
  1293. X      Boolean    Show_Last;        /* xmail show latest option -ls */
  1294. X  } XmailResources;
  1295. X  
  1296. X*** ../v1.0/directory.c    Sun May 27 21:05:49 1990
  1297. X--- directory.c    Sun May 27 21:09:58 1990
  1298. X***************
  1299. X*** 46,52 ****
  1300. X  String        *params;
  1301. X  Cardinal    *num_params;
  1302. X  {
  1303. X!  Arg        args[MAXARGS];
  1304. X   Cardinal    label_width, path_length, n, depth, x, y;
  1305. X   DIR        *new_dir, *dirp;
  1306. X   String        name, path;
  1307. X--- 46,52 ----
  1308. X  String        *params;
  1309. X  Cardinal    *num_params;
  1310. X  {
  1311. X!  Arg        args[6];
  1312. X   Cardinal    label_width, path_length, n, depth, x, y;
  1313. X   DIR        *new_dir, *dirp;
  1314. X   String        name, path;
  1315. X***************
  1316. X*** 106,121 ****
  1317. X      if (label_width) {
  1318. X      (void) sprintf(trans, b_Trans, depth, name);
  1319. X  
  1320. X!     n = 0;
  1321. X!     XtSetArg(args[n], XtNwidth, label_width);                n++;
  1322. X!     XtSetArg(args[n], XtNfont, TextFontStr);                n++;
  1323. X!     XtSetArg(args[n], XtNcallback, callbacks);                n++;
  1324. X!     XtSetArg(args[n], XtNtranslations, XtParseTranslationTable(trans));    n++;
  1325. X  /*
  1326. X  ** create the menu buttons
  1327. X  */
  1328. X      bw = NULL;
  1329. X!     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp), n = 4) {
  1330. X          if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
  1331. X  /*
  1332. X  ** If this 'folder file' is also a directory, mark it with a trailing slash '/'
  1333. X--- 106,120 ----
  1334. X      if (label_width) {
  1335. X      (void) sprintf(trans, b_Trans, depth, name);
  1336. X  
  1337. X!     XtSetArg(args[0], XtNwidth, label_width);
  1338. X!     XtSetArg(args[1], XtNfont, TextFontStr);
  1339. X!     XtSetArg(args[2], XtNcallback, callbacks);
  1340. X!     XtSetArg(args[3], XtNtranslations, XtParseTranslationTable(trans));
  1341. X  /*
  1342. X  ** create the menu buttons
  1343. X  */
  1344. X      bw = NULL;
  1345. X!     for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  1346. X          if (strcmp(dp->d_name, ".") && strcmp(dp->d_name, "..")) {
  1347. X  /*
  1348. X  ** If this 'folder file' is also a directory, mark it with a trailing slash '/'
  1349. X***************
  1350. X*** 124,135 ****
  1351. X             sprintf(s, "%s/%s", path, dp->d_name);
  1352. X             if ((new_dir = opendir(s)) != NULL) {
  1353. X                sprintf(tmp, "%s/", dp->d_name);
  1354. X!               XtSetArg(args[n], XtNlabel, tmp);
  1355. X               } else
  1356. X!               XtSetArg(args[n], XtNlabel, dp->d_name);
  1357. X!        n++;
  1358. X!            XtSetArg(args[n], XtNfromVert, bw);                n++;
  1359. X!            bw = XtCreateManagedWidget("menubutton",commandWidgetClass,layout,args,n);
  1360. X  /*
  1361. X  ** If this 'folder' is a directory, add a button popup menu of its files.
  1362. X  */
  1363. X--- 123,133 ----
  1364. X             sprintf(s, "%s/%s", path, dp->d_name);
  1365. X             if ((new_dir = opendir(s)) != NULL) {
  1366. X                sprintf(tmp, "%s/", dp->d_name);
  1367. X!               XtSetArg(args[4], XtNlabel, tmp);
  1368. X               } else
  1369. X!               XtSetArg(args[4], XtNlabel, dp->d_name);
  1370. X!            XtSetArg(args[5], XtNfromVert, bw);
  1371. X!            bw = XtCreateManagedWidget("menubutton",commandWidgetClass,layout,args,6);
  1372. X  /*
  1373. X  ** If this 'folder' is a directory, add a button popup menu of its files.
  1374. X  */
  1375. X*** ../v1.0/environs.c    Sun May 27 21:05:50 1990
  1376. X--- environs.c    Sun May 27 21:11:35 1990
  1377. X***************
  1378. X*** 40,46 ****
  1379. X  {
  1380. X   static    char    tmp[BUFSIZ];
  1381. X   static    char    buf[BUFSIZ];
  1382. X!  char        *s, *p, *list, *value;
  1383. X   int        i, n;
  1384. X   FILE        *fp;
  1385. X  
  1386. X--- 40,46 ----
  1387. X  {
  1388. X   static    char    tmp[BUFSIZ];
  1389. X   static    char    buf[BUFSIZ];
  1390. X!  char        *s, *p, *list, *value, *index();
  1391. X   int        i, n;
  1392. X   FILE        *fp;
  1393. X  
  1394. X***************
  1395. X*** 50,55 ****
  1396. X--- 50,61 ----
  1397. X      strcpy(tmp, name);
  1398. X  /*
  1399. X  ** If not already done, extract the mail alias list and build the alias table.
  1400. X+ **
  1401. X+ ** We also provide support for the alias alias group, and the possibility that
  1402. X+ ** the user has entered multiple names for an alias without comma separation,
  1403. X+ ** or that mail has handed us a list with wierd comma combinations due to the
  1404. X+ ** user's attempts to include commas in the list.  Support is also provided
  1405. X+ ** for processing continuation lines, if we had to read the .mailrc ourselves.
  1406. X  */
  1407. X   if (! aliases) {
  1408. X      if (mailpid)
  1409. X***************
  1410. X*** 59,66 ****
  1411. X         list = XtMalloc(i);
  1412. X         strcpy(list, "");
  1413. X         if ((fp = fopen(mailrcFile(), "r")) != NULL) {
  1414. X!           while (s = fgets(buf, BUFSIZ, fp)) {
  1415. X!              if (strncmp(buf, "alias", 5) == 0) {
  1416. X                  for (s = &buf[5]; *s == ' ' || *s == '\t'; s++);
  1417. X                  if (strlen(list) + strlen(s) > i) {
  1418. X                     i += BUFSIZ;
  1419. X--- 65,73 ----
  1420. X         list = XtMalloc(i);
  1421. X         strcpy(list, "");
  1422. X         if ((fp = fopen(mailrcFile(), "r")) != NULL) {
  1423. X!           s = fgets(buf, BUFSIZ, fp);
  1424. X!           while (s) {
  1425. X!              if (strncmp(buf,"alias",5) == 0 || strncmp(buf,"group",5) == 0) {
  1426. X                  for (s = &buf[5]; *s == ' ' || *s == '\t'; s++);
  1427. X                  if (strlen(list) + strlen(s) > i) {
  1428. X                     i += BUFSIZ;
  1429. X***************
  1430. X*** 68,85 ****
  1431. X                    }
  1432. X                  strcat(list, s);
  1433. X                 }
  1434. X              }
  1435. X            fclose(fp);
  1436. X           }
  1437. X        }
  1438. X      for (i = 1, p = list; *p; p++) if (*p == '\n') i++;
  1439. X      aliases = (AliasRec **) XtMalloc((i + 1) * sizeof(AliasRec *));
  1440. X! 
  1441. X      for (n = 0, p = list; n < i && *p; n++, p++) {
  1442. X          aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
  1443. X          for (aliases[n]->name = p; *p && *p != ' ' && *p != '\t'; p++);
  1444. X          for (*p++ = '\0'; *p && (*p == ' ' || *p == '\t'); p++);
  1445. X!         for (aliases[n]->alias = p; *p && *p != '\n'; p++);
  1446. X          if (*p) *p = '\0';
  1447. X         }
  1448. X      aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
  1449. X--- 75,128 ----
  1450. X                    }
  1451. X                  strcat(list, s);
  1452. X                 }
  1453. X+              if (s[strlen(s) - 2] != '\\')    /* if not a continuation line */
  1454. X+                 s = fgets(buf, BUFSIZ, fp);    /* just read the next line */
  1455. X+              else {                /* resolve continuation lines */
  1456. X+                 while ((s = fgets(buf,BUFSIZ,fp)) && s[strlen(s)-2] == '\\') {
  1457. X+                       strcpy(&list[strlen(list) - 2], " ");
  1458. X+                       for (; *s == ' ' || *s == '\t'; s++);
  1459. X+                       if (strlen(list) + strlen(s) + 1 > i) {
  1460. X+                          i += BUFSIZ;
  1461. X+                          list = XtRealloc(list, i);
  1462. X+                         }
  1463. X+                       strcat(list, s);
  1464. X+                      }
  1465. X+                 if (s) {
  1466. X+                    strcpy(&list[strlen(list) - 2], " ");
  1467. X+                    for (; *s == ' ' || *s == '\t'; s++);
  1468. X+                    if (strlen(list) + strlen(s) + 1 > i) {
  1469. X+                       i += BUFSIZ;
  1470. X+                       list = XtRealloc(list, i);
  1471. X+                      }
  1472. X+                    strcat(list, s);
  1473. X+                    s = fgets(buf, BUFSIZ, fp);
  1474. X+                   }
  1475. X+                }
  1476. X              }
  1477. X            fclose(fp);
  1478. X           }
  1479. X        }
  1480. X+ /*
  1481. X+ ** count up the number of aliases in the list and allocate the list size
  1482. X+ */
  1483. X      for (i = 1, p = list; *p; p++) if (*p == '\n') i++;
  1484. X      aliases = (AliasRec **) XtMalloc((i + 1) * sizeof(AliasRec *));
  1485. X! /*
  1486. X! ** Copy the pointers for the alias names and values into an array, marking
  1487. X! ** the ends of each with a null and separating any multiple values with a
  1488. X! ** comma.  Ensure there is no trailing comma in the value list.
  1489. X! */
  1490. X      for (n = 0, p = list; n < i && *p; n++, p++) {
  1491. X          aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
  1492. X+         for (; *p && (*p == ' ' || *p == '\t'); p++);
  1493. X          for (aliases[n]->name = p; *p && *p != ' ' && *p != '\t'; p++);
  1494. X          for (*p++ = '\0'; *p && (*p == ' ' || *p == '\t'); p++);
  1495. X!         for (aliases[n]->alias = p; *p && *p != '\n'; p++) {
  1496. X!             if ((*p == ' ' || *p == '\t') && *(p+1) && *(p+1) != '\n' &&
  1497. X!                *(p-1) != *p && *(p-1) != ',') *p = ',';
  1498. X!            }
  1499. X!         for (s = p - 1; *s == ',' || *s == ' ' || *s == '\t'; s--);
  1500. X!         if (*++s == ',' || *s == ' ' || *s == '\t') *s = '\0';
  1501. X          if (*p) *p = '\0';
  1502. X         }
  1503. X      aliases[n] = (AliasRec *) XtMalloc(sizeof(AliasRec));
  1504. X***************
  1505. X*** 86,95 ****
  1506. X      aliases[n] = NULL;
  1507. X     }
  1508. X  /*
  1509. X! ** If name is made up of more than one word, check each word for aliasing.
  1510. X  */
  1511. X   if (value = tmp) {
  1512. X!     if (strchr(tmp, ',') || strchr(tmp, ' ') || strchr(tmp, '\t')) {
  1513. X         buf[0] = '\0';
  1514. X         for (p = value; *p;) {
  1515. X             for (; *p && *p != ',' && *p != ' ' && *p != '\t'; p++);
  1516. X--- 129,138 ----
  1517. X      aliases[n] = NULL;
  1518. X     }
  1519. X  /*
  1520. X! ** If input is made up of more than one word, check each word for aliasing.
  1521. X  */
  1522. X   if (value = tmp) {
  1523. X!     if (index(tmp, ',') || index(tmp, ' ') || index(tmp, '\t')) {
  1524. X         buf[0] = '\0';
  1525. X         for (p = value; *p;) {
  1526. X             for (; *p && *p != ',' && *p != ' ' && *p != '\t'; p++);
  1527. X***************
  1528. X*** 127,158 ****
  1529. X  
  1530. X  /*
  1531. X  ** @(#)GetMailEnv() - Get environment value from mail or shell
  1532. X  */
  1533. X  char *
  1534. X  GetMailEnv(item)
  1535. X  char    *item;
  1536. X  {
  1537. X!  static char    *mailenv;
  1538. X!  char        *s, *c, *value, *getenv();
  1539. X   char        buf[BUFSIZ];
  1540. X   register int    length;
  1541. X  
  1542. X  
  1543. X   value = NULL;
  1544. X   if (! mailpid) {
  1545. X!     if (! (value = GetMailrc(item))) {
  1546. X!        if ((s = getenv(item)) != NULL)
  1547. X            value = XtNewString(s);
  1548. X        }
  1549. X     } else {
  1550. X!     if (! mailenv)
  1551. X!        mailenv = QueryMail("set");
  1552. X  
  1553. X!     for (s = mailenv; *s && strncmp(s, item, strlen(item)); s++)
  1554. X          for (; *s && *s != '\n'; s++);
  1555. X  
  1556. X      if (! *s) {
  1557. X!        if (s = getenv(item))
  1558. X            value = XtNewString(s);
  1559. X        } else {
  1560. X         for (; *s && *s != '"' && *s != '\n'; s++);
  1561. X--- 170,204 ----
  1562. X  
  1563. X  /*
  1564. X  ** @(#)GetMailEnv() - Get environment value from mail or shell
  1565. X+ **                    Accomodate the case of trailing blanks on the item.
  1566. X  */
  1567. X  char *
  1568. X  GetMailEnv(item)
  1569. X  char    *item;
  1570. X  {
  1571. X!  char        *mailenv, *s, *c, *value, *getenv();
  1572. X   char        buf[BUFSIZ];
  1573. X   register int    length;
  1574. X  
  1575. X  
  1576. X   value = NULL;
  1577. X+  strcpy(buf, item);
  1578. X+  for (length = 0; buf[length] && buf[length] != ' '; length++);
  1579. X+  buf[length] = '\0';
  1580. X+ 
  1581. X   if (! mailpid) {
  1582. X!     if (! (value = GetMailrc(buf))) {
  1583. X!        if ((s = getenv(buf)) != NULL)
  1584. X            value = XtNewString(s);
  1585. X        }
  1586. X     } else {
  1587. X!     mailenv = QueryMail("set");
  1588. X  
  1589. X!     for (s = mailenv; *s && strncmp(s, buf, length); s++)
  1590. X          for (; *s && *s != '\n'; s++);
  1591. X  
  1592. X      if (! *s) {
  1593. X!        if (s = getenv(buf))
  1594. X            value = XtNewString(s);
  1595. X        } else {
  1596. X         for (; *s && *s != '"' && *s != '\n'; s++);
  1597. X***************
  1598. X*** 166,171 ****
  1599. X--- 212,218 ----
  1600. X            value[length] = '\0';
  1601. X           }
  1602. X        }
  1603. X+     XtFree(mailenv);
  1604. X     }
  1605. X   return(value);
  1606. X  } /* GetMailEnv */
  1607. X***************
  1608. X*** 172,202 ****
  1609. X  
  1610. X  
  1611. X  /*
  1612. X! ** @(#)mailrcFile() - Return a pointer to fully qualified mailrc file name
  1613. X  */
  1614. X  char *
  1615. X  mailrcFile()
  1616. X  {
  1617. X!  char        *s, *h, *p, *getenv();
  1618. X   static char    buf[BUFSIZ];
  1619. X  
  1620. X!  if ((s = getenv("MAILRC")) == NULL) {
  1621. X      if ((s = getenv("HOME")) == NULL) s = "";
  1622. X      sprintf(buf, "%s/.mailrc", s);
  1623. X-    } else {
  1624. X-     if (*s == '/' || (*s != '~' && *s != '$')) sprintf(buf, "%s", s);
  1625. X-     else {
  1626. X-        if (*s == '~') {
  1627. X-           if ((h = getenv("HOME")) == NULL) h = "";
  1628. X-              sprintf(buf, "%s%s", h, &s[1]);
  1629. X-          } else {
  1630. X-           for (p = s; *p && (*p == '$' || *p == '{' || *p == '('); p++);
  1631. X-           for (s = p; *s && *s != '}' && *s != ')'; s++);
  1632. X-           *s++ = '\0';
  1633. X-           if ((h = getenv(p)) == NULL) h = "";
  1634. X-           sprintf(buf, "%s/%s", h, s);
  1635. X-          }
  1636. X-       }
  1637. X     }
  1638. X   return((char *)buf);
  1639. X  } /* mailrcFile */
  1640. X--- 219,237 ----
  1641. X  
  1642. X  
  1643. X  /*
  1644. X! ** @(#)mailrcFile() - Return a path to environment or default .mailrc file
  1645. X  */
  1646. X  char *
  1647. X  mailrcFile()
  1648. X  {
  1649. X!  char        *s, *getenv();
  1650. X   static char    buf[BUFSIZ];
  1651. X  
  1652. X!  if (s = getenv("MAILRC"))
  1653. X!     (void) strcpy(buf, s);
  1654. END_OF_FILE
  1655. if test 46474 -ne `wc -c <'Patch.01b'`; then
  1656.     echo shar: \"'Patch.01b'\" unpacked with wrong size!
  1657. fi
  1658. # end of 'Patch.01b'
  1659. fi
  1660. echo shar: End of archive 1 \(of 5\).
  1661. cp /dev/null ark1isdone
  1662. MISSING=""
  1663. for I in 1 2 3 4 5 ; do
  1664.     if test ! -f ark${I}isdone ; then
  1665.     MISSING="${MISSING} ${I}"
  1666.     fi
  1667. done
  1668. if test "${MISSING}" = "" ; then
  1669.     echo You have unpacked all 5 archives.
  1670.     rm -f ark[1-9]isdone
  1671. else
  1672.     echo You still need to unpack the following archives:
  1673.     echo "        " ${MISSING}
  1674. fi
  1675. ##  End of shell archive.
  1676. exit 0
  1677.  
  1678. dan
  1679. ----------------------------------------------------
  1680. O'Reilly && Associates   argv@sun.com / argv@ora.com
  1681. Opinions expressed reflect those of the author only.
  1682.